﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BhServer;
using System.ServiceModel;
using BhServer.Comunication;

namespace BhClient
{
    public partial class Form1 : Form, IUpdateServerServiceCallback, IChatServiceCallback
    {
        public Form1()
        {
            InitializeComponent();
            t.Name = "Connect";
            t.TaskFinished += new EventHandler(t_TaskFinished);
            t.TaskPerformed += new ProgNetComponentsDx.Tasks.PerformTaskHandler(t_TaskPerformed);
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            t.Cancel();
        }
        
        void t_TaskPerformed(object sender, ProgNetComponentsDx.Tasks.TaskResultEventArgs e)
        {
            while (true)
            {
                e.ThrowIfCancellationRequested();
                
                if (!IsConnected())
                {
                    id = -1;
                    SetText("Not connected");
                    Connect();
                }
                else
                {
                    SetText("Connected");
                }
                for (int i = 0; i < 10; i++)
                {
                    e.ThrowIfCancellationRequested();
                    System.Threading.Thread.Sleep(1000);
                }
            }
        }
        
        private bool IsConnected()
        {
            if (IChatServiceProxy == null)
                return false;
            try
            {
                IChatServiceProxy.Beep();
                return true;
            }
            catch { }
            return false;
        }
        
        private void SetText(string txt)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<string> (SetText), txt);
                return;
            }
            this.Text = txt;
        }
        
        void t_TaskFinished(object sender, EventArgs e)
        {
            Append("Finished: " + t.Status);
            ClearProxy();
        }
        private void ClearProxy()
        {
            IChatServiceProxy = null;
            IUpdateServerServiceProxy = null;
            id = -1;
        }
        IUpdateServerService IUpdateServerServiceProxy;
        IChatService IChatServiceProxy;
        private int id;

        private void Connect()
        {
            try
            {
                string endPointAddr = "net.tcp://172.29.3.5:8000/BHServer";
                NetTcpBinding tcpBinding = new NetTcpBinding();
                tcpBinding.TransactionFlow = false;
                tcpBinding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
                tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
                tcpBinding.Security.Mode = SecurityMode.None;

                Append("Attempt to connect to: " + endPointAddr);
                var ctx = new InstanceContext(this);
                
                IUpdateServerServiceProxy = DuplexChannelFactory<IUpdateServerService>.CreateChannel(this, tcpBinding, new EndpointAddress(endPointAddr + "/Update"));
                IChatServiceProxy = DuplexChannelFactory<IChatService>.CreateChannel(this, tcpBinding, new EndpointAddress(endPointAddr + "/Chat"));

                //IUpdateServerServiceProxy = DuplexChannelFactory<IUpdateServerService>.CreateChannel(ctx, "*");
                //IChatServiceProxy = DuplexChannelFactory<IChatService>.CreateChannel(this, "Chat");
                

                //proxy = ChannelFactory<IUpdateServerService>.CreateChannel(tcpBinding, endpointAddress);
                id = IChatServiceProxy.LogIn(textEdit1.Text);
                IUpdateServerServiceProxy.Connect(id);
            }
            catch (Exception ex)
            {
                Append(ex.Message);
                ClearProxy();
            }
        }
        
        ProgNetComponentsDx.Tasks.BaseEventTask t = new ProgNetComponentsDx.Tasks.BaseEventTask();

        private void btnLogIn_Click(object sender, EventArgs e)
        {
            t.Run();
        }

        void Append(string text)
        {
            if (meLog.InvokeRequired)
            {
                meLog.Invoke(new Action<string>(Append), text);
                return;
            }
            meLog.AppendLine(text);
            meLog.ScrollToCaret();
        }

        private void btnLogOut_Click(object sender, EventArgs e)
        {
            try
            {
                if (IsConnected())
                {
                    IChatServiceProxy.LogOut(this.id);
                }
            }
            finally
            {
                t.Cancel();
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (IsConnected())
            {
                try
                {
                    var ver = IUpdateServerServiceProxy.GetLatestVersion();
                    Append("Version: " + ver.ToString());
                }
                catch (Exception ex)
                {
                    Append(ex.Message);
                }
            }
        }

        public void Notify()
        {
            
        }

        public void NotifyUserConnected(ChatUser user)
        {
            Append("User connected:" + user.Name);
        }

        public void NotifyUserDisconnected(ChatUser user)
        {
            Append("User disconnected:" + user.Name);
        }


        public void NotifyNewVersion(Version newVersion)
        {
            Append("New wersion: " + newVersion.ToString());
        }
    }
}
